package com.gainloop;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;

import javax.management.RuntimeErrorException;

import org.alexd.jsonrpc.JSONRPCException;

import com.gainloop.Adapters.HelpAdapter;
import com.gainloop.Api.ApiResponseObject;
import com.gainloop.Api.Categories;

import com.gainloop.Api.Helps;
import com.gainloop.Api.Tags;
import com.gainloop.Api.Users;
import com.gainloop.Api.Wishes;
import com.gainloop.Api.Entity.Category;
import com.gainloop.Api.Entity.Help;
import com.gainloop.Api.Entity.Tag;
import com.gainloop.Api.Entity.Wish;

import com.gainloop.Api.Entity.User;
import com.gainloop.Data.Registry;

import com.gainloop.Utils.Constants;
import com.gainloop.Utils.ImageThreadLoader;
import com.gainloop.Utils.ImageThreadLoader.ImageLoadedListener;
import com.ocpsoft.pretty.time.PrettyTime;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;

import android.text.Html;
import android.util.Log;
import android.view.Menu;

import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

// TODO copy design from profile pages
public class GainPage extends ActivityAbstract{
	static final public String GAIN_ID = "gain_id" ;
	private ArrayList<Help> helps;
	private HelpAdapter helpAdapter;
	private Runnable viewHelps;
	private Wish wish;
	private ProgressDialog progressDialog = null;
	private LinearLayout pageLayout;
	
	private static int MIN_HELP_DESC_LENGTH = 3;
	private static int MAX_HELP_DESC_LENGTH = 1000;

	private Long gainId;
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gainpage);
		
		initHeader();
		headerTitle.setText(R.string.wish);
		 
		gainId = getIntent().getExtras().getLong(GAIN_ID);
		Log.v("GainPage","gain id: "+gainId);
		createPage();
		
		
	}
	
	/**
	 * Creates the page.
	 * @param gainId : according to the given Gain Id.
	 */
	private void createPage() {
		
	
		pageLayout=(LinearLayout)findViewById(R.id.wish_page_layout);
		pageLayout.setVisibility(View.INVISIBLE);
		
		viewHelps = new Runnable() {
			@Override
			public void run() {
					wish = getWishById(gainId);
					if (wish==null){
						Log.v("wish is","null");
						throw new RuntimeException("wish not found");
					}
					getHelps();
					runOnUiThread(showUI);
				//runOnUiThread(returnRes);
					
				
			}
		};
		Thread thread = new Thread(null, viewHelps, "MagentoBackground");


		progressDialog = ProgressDialog.show(GainPage.this,getString(R.string.wait_msg),
				getString(R.string.ret_data_msg), true);
		
		thread.start();
		
		
	}
	private Runnable showUI = new Runnable() {

		@Override
		public void run() {
			
			TextView show_wish_desc = (TextView) findViewById(R.id.show_wish_desc);
			TextView show_wish_category = (TextView) findViewById(R.id.show_gain_category);
			TextView show_wish_tags = (TextView) findViewById(R.id.show_gain_tags);
			TextView show_wish_status = (TextView) findViewById(R.id.show_gain_status);
			TextView show_wish_created = (TextView) findViewById(R.id.show_gain_created);
			ScrollView mainScrollView=(ScrollView)findViewById(R.id.main_scroll);
			mainScrollView.scrollTo(0, 0);
			Button cancel_button = (Button)findViewById(R.id.cancel_wish_button);
			cancel_button.setVisibility(View.INVISIBLE);
			
			
			final EditText add_wish_help_description = (EditText) findViewById(R.id.add_gain_help_description);
			Button gain_page_help_button = (Button) findViewById(R.id.gain_page_help_button);
			ListView helpsList=(ListView) findViewById(R.id.helpsList);
			helpAdapter = new HelpAdapter(GainPage.this, R.layout.wish_item, new ArrayList<Help>());
			helpsList.setAdapter(helpAdapter);
			
			PrettyTime p=new PrettyTime();
			if (wish.getCreateTime().after(new Date(0))){
				show_wish_created.setText(p.format(wish.getCreateTime()));
			}
			else{
				show_wish_created.setText("unknown");
			}
			addCreatedTime(show_wish_created);
			addTags(show_wish_tags,wish);
			addCategory(show_wish_category,wish);
			final User wishUser = getWishUser(wish);
			
			String username=wishUser.getName();
			//TODO find more elegant way to do that.
			show_wish_desc.setText(Html.fromHtml("<B><FONT COLOR=\"#acd62e\">"+username +" </B></FONT>"+" wishes to "+ wish.getContent()));
			
			Long curUserId = Registry.GetUser().getId();
			
			if(curUserId==wish.getUserId()){ //User should not help himself! - Meir
				gain_page_help_button.setVisibility(View.INVISIBLE);
				add_wish_help_description.setVisibility(View.INVISIBLE);
				LinearLayout page_layout = (LinearLayout)findViewById(R.id.wish_page_layout);
				page_layout.removeViewInLayout(gain_page_help_button);
				page_layout.removeViewInLayout(add_wish_help_description);
				
				cancel_button.setVisibility(View.VISIBLE);
				cancel_button.setOnClickListener(new CancelButtonListener());
				helpAdapter.setOwnerWish();
			}
			else {
				String wishUserName = wishUser.getName();
				showHelp(gain_page_help_button,add_wish_help_description,gainId,wishUserName,curUserId);
			}
			
			addUserPic(show_wish_desc,wishUser.getFbId());
			
			//making the image and text to link to the user profile page.
			show_wish_desc.setOnClickListener(new View.OnClickListener() {		
				@Override
				public void onClick(View arg0) {
					Intent intent = new Intent(GainPage.this,Profile.class).putExtra(Constants.userParam, wishUser.getId());
					startActivity(intent);
				}
			});
			
		    show_wish_status.setText(Wish.statusToString(wish.getStatus()));
		    
		    if (helps != null && helps.size() > 0) {
				//helpAdapter.notifyDataSetChanged();
				
				for (int i = 0; i < helps.size(); i++){
					helpAdapter.add(helps.get(i));
				}
			}
		    
		    pageLayout.setVisibility(View.VISIBLE);
		    progressDialog.dismiss();
			
		}
	};
	private void getHelps(){
		try {
			helps=Helps.getInstance().getAllByWish(wish);
			
		} catch (JSONRPCException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		
		
	}
	private void addCreatedTime(TextView show_wish_created){
		PrettyTime p=new PrettyTime();
		if (wish.getCreateTime().after(new Date(0))){
			show_wish_created.setText(p.format(wish.getCreateTime()));
		}
		else{
			show_wish_created.setText("unknown");
		}
	}
	/**
	 * Adds the View for the ability to help the user wish.
	 * @param gain_page_help_button
	 * @param add_wish_help_description
	 * @param wishId
	 * @param wishUserName 
	 * @param curUserId
	 */
	private void showHelp(Button gain_page_help_button,
			final EditText add_wish_help_description, final Long wishId, String wishUserName, final Long curUserId) {
		gain_page_help_button.append(" "+wishUserName+"!");
		gain_page_help_button.setOnClickListener(new View.OnClickListener() {
			
        	public void onClick(View v) {
        		String helpDesc = add_wish_help_description.getText().toString();
        		
        		if(helpDesc.length()<MIN_HELP_DESC_LENGTH){
        			Toast.makeText(GainPage.this, "Help description to short!", Toast.LENGTH_SHORT).show();
        			return;
        		}
        		if(helpDesc.length()>MAX_HELP_DESC_LENGTH){
        			Toast.makeText(GainPage.this, "Help description to long!", Toast.LENGTH_SHORT).show();
        			return;
        		}
        		add_wish_help_description.setText("");
        		 
        		Help newHelp = new Help();
        		newHelp.setContent(helpDesc);
        		newHelp.setUserId(curUserId);
        		newHelp.setWishId(wishId);
        		ApiResponseObject<Help> resp;
        		try {
        			
        				resp=Helps.getInstance().create(newHelp);
        			
					if (resp.getReturnCode()==0){
						helpAdapter.add(newHelp);
						helpAdapter.notifyDataSetChanged();
					}
					else{
						Constants.declareInternalError(GainPage.this,"Error: " +resp.getError()+" , Please try again..");

					}
				} catch (JSONRPCException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Constants.declareInternalError(GainPage.this, "Error sending help, Please try again..");
				}
				
				
            }
        });
		
	}

	/**
	 *  Adds the user Fb profile pic to the view. 
	 * @param show_gain_desc : the  view
	 * @param fbId : the FaceBook id.
	 */
	private void addUserPic(TextView show_gain_desc, long fbId) {
		final ImageView image = (ImageView) this.findViewById(R.id.gain_page_img);
	    //InputStream is = (InputStream)content;
	   // Drawable image;// = Drawable.createFromStream(is, "src");
	    Bitmap cachedImage;
		try {
			cachedImage = ImageThreadLoader.GetInstance().loadImage("http://graph.facebook.com/" + fbId + "/picture?type=square", 
					new ImageLoadedListener() {
				public void imageLoaded(Bitmap imageBitmap) {
					image.setImageBitmap(imageBitmap);
					               
				}
			});
			if(cachedImage != null)
				image.setImageBitmap(cachedImage);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	     
	     
	}
	
	/**
	 * Addes the category to the view. 
	 * @param show_gain_category : the  view
	 * @param wish : the wish from where to extract its category.
	 */
	private void addCategory(TextView show_gain_category, Wish wish) {
		Category category = getCategory(wish.getCategoryId());
		
		String categoryName = null;
		if(category!=null){
			categoryName= category.getName();
		}
		else{
			categoryName = "";
		}
		show_gain_category.setText(categoryName);
	}
	
	/**
	 * Adds the wish tags to the view.
	 * @param show_wish_tags : the view to add the tags.
	 * @param wish : the wish from where to extract its Tags.
	 */
	private void addTags(TextView show_wish_tags, Wish wish) {
		Tags tags = new Tags();
		ArrayList<Tag> tagsArray = null;
		try {
			
				tagsArray = tags.getAllByWish(wish);
			
		} catch (JSONRPCException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		
		
		StringBuffer allTagsStr = new StringBuffer();
		//allTagsStr.append("cat, dog");
		boolean first=true;
		for(Tag curTag:tagsArray){
			if (first){
				first=false;
			}
			else{
				allTagsStr.append(", ");
			}
			allTagsStr.append(curTag.getName());
			
		}
		show_wish_tags.append(" "+allTagsStr);
	}
	
	/**
	 * Gets the Category object by its ID. 
	 * @param categoryId 
	 * @return Category object
	 */
	private Category getCategory(long categoryId) {
		Categories categories = new Categories();
		ApiResponseObject<Category> resp = null;
		try {
			
				resp = categories.getById(categoryId);
			
		} catch (JSONRPCException e) {
			e.printStackTrace();
			throw new RuntimeException("server side error");
		}
		Category category = null;
		category=resp.getData();
		return category;
	}
	
	/**
	 * Gets a wish by its id
	 * @param wishId
	 * @return wish
	 */
	private Wish getWishById(Long wishId) {
		Wishes wishes = Wishes.getInstance();
		ApiResponseObject<Wish> resp = null;
		try {
			
			resp = wishes.getById(wishId);
			
		} catch (JSONRPCException e) {
			e.printStackTrace();
			throw new RuntimeException("server side error");
		}
		Wish wish = null;
		if (resp!=null)
			wish=resp.getData();
		return wish;
	}
	
	/**
	 * Gets the User that holds the given wish.
	 * @param wish : the wish that the user holds.
	 * @return User : the user that holds that wish(that created it).
	 */
	private User getWishUser(Wish wish) {
		Users users = new Users();
		ApiResponseObject<User> resp = null; 
		try {
		
				resp = users.getById(wish.getUserId());
			
		} catch (JSONRPCException e) {
			e.printStackTrace();
			throw new RuntimeException("server side error");
		}
		User user = null;
		user=resp.getData();
		return user;
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) { 
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		
		MenuItem mi_profile = menu.findItem(R.id.menuProfile);
		mi_profile.setIntent(new Intent(this, Profile.class));
		
		MenuItem mi_newWish = menu.findItem(R.id.menuNewWish);
		mi_newWish.setIntent(new Intent(this, AddWish.class));
		
		MenuItem mi_home_gain = menu.findItem(R.id.menuHome);
		mi_home_gain.setIntent(new Intent(this, Home.class));
		
		MenuItem mi_search_gain = menu.findItem(R.id.menuSearch); 
		mi_search_gain.setIntent(new Intent(this, GainSearch.class));
		
		MenuItem mi_people = menu.findItem(R.id.menuPeople); 
		mi_people.setIntent(new Intent(this, People.class));
		
		return true;
	}
	
	public boolean onOptionsItemSelected (MenuItem item){
		return false;		
    }
	
	public class CancelButtonListener  implements View.OnClickListener{
		
		@Override
		public void onClick(View arg0) {
			showCancelDialog();
		}
	}
	
	public void showCancelDialog(){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("Are you sure you want to cancel this wish?").setCancelable(false)
		       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		        	   cancelWish();
		           }
		       })
		       .setNegativeButton("No", new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		                dialog.cancel();
		           }
		       });
		AlertDialog alert = builder.create();
		alert.show();
	}
	
	/**
	 * Cancels the current wish.
	 */
	private void cancelWish(){
		Wishes wishes = Wishes.getInstance();
		try {
			wishes.setWishCanceled(wish);
		} catch (JSONRPCException e) {
			Constants.declareInternalError(getApplicationContext());
			e.printStackTrace();
			return;
		}
		Log.v("wish ","was deleted");
		Toast toast = Toast.makeText(GainPage.this, "Wish was cancelled",Toast.LENGTH_SHORT);
		toast.show();
		Intent intent = new Intent(GainPage.this,Home.class);
		GainPage.this.startActivity(intent);
	}
}
